<template>
  <div id="cesiumContainer">
    <el-button class="setParadata" type="primary" @click="setParadata">参数设置</el-button>
    <el-button class="data-simulation" type="primary" @click="getSimulationData">卫星模拟</el-button>
    <el-button class="seeHistoryBtn" type="primary" @click="seeHistory">历史任务</el-button>
    <div v-if=this.setParaBool class="right-menu">
      <!-- 设置监测站 -->
      <el-card :bordered="false" style="margin-bottom: 2px;">
        <div slot="header" style="font-weight: bold;">
          <span style="font-size:larger;">设置监测站</span>
        </div>
        <div style="margin-bottom:10px;margin-top:10px;  display: flex; align-items: center;">
          <div style="margin-right:10px; ">监测站范围左下:</div>
          <el-input v-model="setReceiveStation.leftBottom" placeholder="请输入经纬度,以“,”隔开" clearable
            style="width: 64%; height: 28px" />
        </div>
        <div style="margin-bottom:10px; display: flex; align-items: center;">
          <div style="margin-right:10px; ">监测站范围右上:</div>
          <!-- <div style="width:12px"></div>       -->
          <el-input v-model="setReceiveStation.rightTop" placeholder="请输入经纬度,以“,”隔开" clearable
            style="width: 64%; height: 28px" />
        </div>
        <div style="margin-bottom:10px; " v-show="satellitePosStr == '' ? false : true">
          <div style="margin-right:10px;">卫星位置:</div>
          <el-input v-model="satellitePosStr" :disabled=true style="width: 98%; margin-bottom: 5px; margin-top: 5px;"
            :autosize="{ minRows: 2, maxRows: 2 }" type="textarea" placeholder="" />
        </div>

        <!-- 分布方式 -->
        <div style="display: flex; align-items: center;">
          <div>分布方式:</div>
          <div style="width:26px"></div>
          <div style="display: flex; justify-content: flex-end; align-items: center;">
            <el-radio-group v-model="setReceiveStation.getType" size="" @change="changeReceiveStationType">
              <el-radio-button :label="0" style="margin-left: 0px;">格网部署</el-radio-button>
              <el-radio-button :label="1" style="margin-left: 0px;">随机部署</el-radio-button>
              <el-radio-button :label="2" style="margin-left: 0px;">位置导入</el-radio-button>
            </el-radio-group>
          </div>
        </div>
        <!-- 格网部署 -->
        <div v-if="setReceiveStation.getType == 0">
          <div style="margin-top:10px; display: flex; align-items: center;margin-bottom: 5px;">
            <div style="margin-right:7px; ">监测站间隔:</div>
            <div style="width:35px"></div>
            <el-input v-model="setReceiveStation.distance" placeholder="" clearable style="width: 64%; height: 28px" />
          </div>
        </div>
        <!-- 随机部署 -->
        <div v-if="setReceiveStation.getType == 1">
          <div style="margin-top:10px; display: flex; align-items: center; margin-bottom: 5px;">
            <div style="margin-right:7px; ">监测站数量:</div>
            <div style="width:13px"></div>
            <el-input v-model="setReceiveStation.number" placeholder="" clearable style="width: 70%; height: 28px" />
          </div>
        </div>
        <!-- 位置导入 -->
        <div v-if="setReceiveStation.getType == 2">
          <el-input v-model="setReceiveStation.clicktextArr" :disabled=true
            style="width: 99%; margin-bottom: 5px; margin-top: 5px;" :autosize="{ minRows: 2, maxRows: 3 }"
            type="textarea" placeholder="" />
        </div>
        <div style="text-align: center; float: right; margin-right: 3px; margin-bottom: 5px;">
          <el-button type="primary" @click="startSetReceiveStation">部署监测站</el-button>
        </div>
      </el-card>

      <!-- 设置干扰源 -->
      <el-card :bordered="false" style="margin-bottom: 2px;">
        <div style="font-size:larger;  font-weight: bold;margin-bottom: 5px;" slot="header">
          <span>设置干扰源</span>
        </div>
        <div style="display: flex; align-items: center;">
          <div>分布方式:</div>
          <div style="width:26px"></div>
          <el-radio-group v-model="setInterferenceSrc.getType" style="float: left; margin-bottom: 5px;" size=""
            @change=changeInterferenceSrcType()>
            <el-radio-button :label="0">自动获取</el-radio-button>
            <el-radio-button :label="1">点选输入</el-radio-button>
            <el-radio-button :label="2">随机生成</el-radio-button>
          </el-radio-group>
        </div>
        <!-- 自动获取 -->
        <div v-if="setInterferenceSrc.getType == 0">
          <el-input v-model="setInterferenceSrc.autotextArr" :disabled=true
            style="width: 99%; margin-bottom: 5px; margin-top: 5px;" :autosize="{ minRows: 3, maxRows: 3 }"
            type="textarea" placeholder="" />
          <div style="text-align: center; float: right; margin-right: 0px; margin-bottom: 5px;">
            <el-button type="primary" @click="startSetInterferenceSrc">开始部署</el-button>
          </div>
        </div>
        <!-- 点选输入 -->
        <div v-if="setInterferenceSrc.getType == 1">
          <el-input v-model="setInterferenceSrc.clicktextArr" :disabled=true
            style="width: 99%; margin-bottom: 5px; margin-top: 5px;" :autosize="{ minRows: 3, maxRows: 3 }"
            type="textarea" placeholder="请点击‘开始点选’后在场景中点选" />
          <div style="text-align: center; float: right; margin-bottom: 5px;">
            <el-button type="primary" :disabled="setInterferenceSrc.clicktextArr != '' ? false : true"
              @click="clearClickForInterferenceSrc">清空当前</el-button>
            <el-button type="primary" @click="clickForInterferenceSrc">{{ setInterferenceSrc.buttonText }}</el-button>
          </div>
        </div>
        <!-- 随机生成 -->
        <div v-if="setInterferenceSrc.getType == 2">
          <div style="margin-top:5px; display: flex; align-items: center;">
            <div style="font-size:medium;margin-right:10px; ">干扰源数量:</div>
            <el-input v-model="setInterferenceSrc.randomInfo.number" placeholder="请输入整数" clearable
              style="width: 73%; height: 28px" />
          </div>
          <div style="margin-top:10px; display: flex; align-items: center;">
            <el-tooltip effect="dark" placement="top-start">
              <template #content>请输入和干扰源数量相同的类型，以‘，’隔开<br />（1:单音,2:多音,3:线性扫平,4:脉冲） </template>
              <div style="font-size:medium;margin-right:10px; ">干扰源类型:</div>
            </el-tooltip>
            <el-input v-model="setInterferenceSrc.randomInfo.type" placeholder="请输入干扰源类型" clearable
              style="width: 73%; height: 28px" />
          </div>
          <div style="margin-top:10px; margin-bottom: 5px; display: flex; align-items: center;">
            <el-tooltip effect="dark" placement="top-start" content="单位：(dBw)">
              <div style="font-size:medium;margin-right:10px; ">干扰源功率:</div>
            </el-tooltip>
            <el-input v-model="setInterferenceSrc.randomInfo.power" placeholder="请输入干扰源功率" clearable
              style="width: 73%; height: 28px" />
          </div>

          <div style="text-align: center; float: right; margin-right: 3px; margin-bottom: 5px;">
            <el-button type="primary" @click="startSetInterferenceSrc"
              :disabled="setInterferenceSrc.autotextArr == '' ? false : true">部署干扰源</el-button>
          </div>
        </div>
      </el-card>

      <!-- 分析计算 -->
      <el-card :bordered="false">
        <div style="font-size:larger;  font-weight: bold;margin-bottom: 10px;" slot="header">
          <span>分析计算</span>
        </div>
        <div style="margin-bottom: 5px; display: flex; align-items: center;">
          <el-tooltip effect="dark" placement="top-start" content="输入整数">
            <div style="margin-right:30px; ">仿真次数:</div>
          </el-tooltip>
          <el-input v-model="simTime" placeholder="" clearable style="width: 72%; height: 28px" />
        </div>
        <div v-show="chartData.show" style="width:100%; height: 300px" id="drawChart"></div>
        <div style="margin-top: 10px; ">
          <el-button style="float: right; margin-bottom: 5px;" type="primary" @click="startCounting">开始分析</el-button>
        </div>
      </el-card>

      <!-- 干扰定位  定位误差 -->
      <el-card :bordered="false" style="margin-bottom: 2px;">
        <div style="font-size:larger;  font-weight: bold;margin-bottom: 10px;" slot="header">
          <span>结果展示</span>
        </div>
        <div style="margin-bottom: 10px; display: flex; align-items: center;">
          <div style="margin-right:10px; ">选择第</div>
          <el-select v-model="stationCNRNum" @change="selectstationCNRNum" style="width: 20%; height: 28px">
            <el-option v-for="CNRNum in simResultNumList" :label="CNRNum.label" :value="CNRNum.value"></el-option>
          </el-select>
          <div style="margin-left:10px; ">次载噪比仿真结果</div>
        </div>
        <div v-show="stationCNRNum == 0 ? false : true">
          <div v-show="simInterferencePosArr == '' ? true : true">
            <div>干扰源定位结果</div>
            <el-input v-model="simInterferencePosArr" :disabled=true
              style="width: 100%; margin-bottom: 5px; margin-top: 5px;" :autosize="{ minRows: 3, maxRows: 3 }"
              type="textarea" placeholder="" />
          </div>
          <div v-show="PosErrorArr == '' ? true : true">
            <div>干扰源定位误差</div>
            <el-input v-model="PosErrorArr" :disabled=true style="width: 100%;margin-top: 5px;"
              :autosize="{ minRows: 3, maxRows: 3 }" type="textarea" placeholder="" />
          </div>

        </div>
      </el-card>

      <!-- 数据入库 -->
      <el-card :bordered="false">
        <div style="font-size:larger;  font-weight: bold;margin-bottom: 10px;" slot="header">
          <span>数据入库</span>
        </div>
        <div style="margin-bottom: 5px; display: flex; align-items: center;">
          <el-tooltip effect="dark" placement="top-start" content="">
            <div style="margin-right:30px;">任务名称:</div>
          </el-tooltip>
          <el-input v-model="currentInfoName" placeholder="" clearable style="width: 72%; height: 28px" />
        </div>
        <div style="margin-top: 10px; ">
          <el-button style="float: right; margin-bottom: 5px;" type="primary"
            @click="pushParamAndResultToSql">确定入库</el-button>
        </div>
      </el-card>

      <!-- 设置障碍物 -->
      <!-- <el-card :bordered="false" style="margin-bottom: 10px;">
      <div style="font-size:larger; margin-bottom: 5px;" slot="header">
        <span>设置障碍物</span>
      </div>
        <el-radio-group v-model="setObstacle.getType" style="float: left" @change=changeObstacle()>
          <el-radio-button :label="0">自动获取</el-radio-button>
          <el-radio-button :label="1">点选输入</el-radio-button>
        </el-radio-group>
      自动获取
      <div v-if="setObstacle.getType == 0">
        <el-input v-model="setObstacle.autotextArr" :disabled=true
          style="width: 100%; margin-bottom: 5px; margin-top: 5px;" :autosize="{ minRows: 4, maxRows: 4 }"
          type="textarea" placeholder="" />
        
          <div style="text-align: center; float: right; margin-right: 0px; margin-bottom: 5px;" >
          <el-button type="primary" @click="startsetObstacle" 
          :disabled="setObstacle.autotextArr == '' ? false : true">开始部署</el-button>
        </div>
      </div>
      点选输入
      <div v-if="setObstacle.getType == 1">
        <el-input v-model="setObstacle.clicktextArr" :disabled=true
          style="width: 100%; margin-bottom: 5px; margin-top: 5px;" :autosize="{ minRows: 4, maxRows: 4 }"
          type="textarea" placeholder="请点击‘开始点选’后在场景中点选" />
        <div style="text-align: center; float: right; margin-bottom: 5px;">
          <el-button type="primary" :disabled="setObstacle.clicktextArr != '' ? false : true"
            @click="clearClickForObstacle">清空当前</el-button>
          <el-button type="primary" @click="clickForObstacle">{{ setObstacle.buttonText }}</el-button>
        </div>
      </div>
    </el-card> -->
    </div>

    <!-- 历史数据 -->
    <div v-if=this.history.seeHistoryBtnBool>
      <div class="history-menu">
        <div style="margin: 10px; display: flex; align-items: center;">
          <div style="font-size:x-large;margin-left:20px;">历史任务</div>
          <div style="font-size:large;margin-right:5px; margin-left:500px;">展示最新</div>
          <el-select style="width: 8%; height: 28px" v-model="history.latestDataNum" @change="selectlatestDataNum"
            placeholder="0">
            <el-option label=5 value=5></el-option>
            <el-option label=10 value=10></el-option>
            <el-option label=30 value=30></el-option>
            <el-option label=50 value=50></el-option>
          </el-select>
          <div style="font-size:large;margin-left:5px; ">条数据</div>
        </div>
        <!-- <div style="height:5px"></div> -->
        <div class="history-table" >
          <el-table :data="history.historyAllInfo" border style="font-size:large;">
            <el-table-column label="名称" prop="name" fixed width="180" align="center"></el-table-column>
            <el-table-column label="时间" prop="createTime" fixed width="200" align="center"></el-table-column>
            <el-table-column label="接收站数量" prop="result.stationNum" fixed width="120" align="center"></el-table-column>
            <el-table-column label="干扰源数量" prop="result.interfPos.length" fixed width="120" align="center"></el-table-column>
            <el-table-column label="仿真次数" prop="result.simTime" fixed width="120" align="center"></el-table-column>
            <el-table-column label="操作" fixed="right" width="120" align="center">
              <template #default="{ row }">
                <div style="display: flex; justify-content: center; align-items: center;">
                  <el-button style="background-color:darkseagreen; color: aliceblue; margin-right: 10px;"
                    @click="seeOneHistoryInfo(row)">
                    结果展示
                  </el-button>
                  <!-- <el-button style="background-color: lightcoral; color: aliceblue"
                    @click="delOneHistoryInfo(row)">
                    删除
                  </el-button> -->
                </div>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>

  </div>

</template>


<script>

import * as Cesium from 'cesium'
import { ElLoading } from 'element-plus';
import * as echarts from 'echarts';
import { getReceiveStationInfo } from '@/api/monitor/station'
import { receiverSim } from '@/api/monitor/station'
import { getInterferenceDataList } from '@/api/monitor/station'
import { interferenceSim } from '@/api/monitor/station'
import { queryJszLastRecord } from '@/api/monitor/station'
import { getJszRecordById } from '@/api/monitor/station'
import { saveJszAnalyseData } from '@/api/monitor/station'
import { interferenceAnalyzeStatic } from '@/api/monitor/station'

export default {
  name: 'Index',
  computed: {

  },

  components: {},

  data() {
    return {
      // 版本号
      version: '3.8.7',
      responseData: '',
      input: '',
      value: true,
      region_switch: false,
      region_x1: '',
      region_y1: '',
      region_x2: '',
      region_y2: '',
      clickCount: '0',
      interference_switch: false,

      jamItems: [{
        name: '',
        x: '',
        y: ''
      }],

      satellitePos: [],
      satellitePosStr: '',
      satelliteEntities: [],

      // 设置监测站
      setReceiveStation: {
        getType: 0,
        receiveStationPos: [],
        clicktextArr: '',
        distance: 0.3,
        number: 30,
        leftBottom: '110,25',
        rightTop: '113,28',
      },

      // 设置干扰源
      setInterferenceSrc: {
        getType: 2,
        interferenceSrcInfo: [],
        // 自动
        autotextArr: '',
        // 手动
        clicktextArr: '',
        // 随机
        randomInfo: {
          number: '3',
          type: '1,1,1',
          power: '40,40,40',
        },
        isSelecting: false,
        handler: null,
        buttonText: '开始点选',
        description: '干扰源',
        modelUri: '/glb/interferenceSrc_true.glb',
        fakerModelUri: '/glb/interferenceSrc_simul.glb',
      },

      // 设置障碍物
      setObstacle: {
        getType: 0,
        autoGetObstacleInfo: [],
        autotextArr: '',

        isSelecting: false,
        handler: null,
        buttonText: '开始点选',
        clicktextArr: '',
        description: '障碍物',
        modelUri: '/glb/obstacle.glb',
      },

      simTime: 0,

      // 载噪比
      stationCNRNum: '0',
      stationCNR: [],
      simResultNumList: [{
        label: 0,
        value: 0,
      }
      ],
      // 定位到的干扰源位置
      detectedInterferencePos: [],
      simInterferencePosArr: '',
      // 定位误差
      PosErrorArr: '',

      // n组结果，定位、误差、平均误差
      nTimePosAndErr: {
        NTimeInterferencePosDetected: [], // x,y
        NTimeLocationError: []
      },
      // chart data
      chartData: {
        chartInit: null,
        option: null,
        chartDom: null,
        show: false,
        x: [],
        y: []
      },

      // 当前所有数据
      currentInfo: {
        rangeLB: null,
        stationType: null,
        stationGridDis: null,
        stationNum: null,
        stationPos: null,
        satellitePos: null,
        interfType: null,
        interfAutoTextArr: null,
        interfClickTextArr: null,
        interfRandNum: null,
        interfRandType: null,
        interfRandPower: null,
        interfPos: null,
        simTime: null,
        nTimePosAndErr: null,
        chartData: null,
        simResultNumList: null
      },
      currentInfoName: "任务一",

      // 历史数据
      history: {
        latestDataNum: 5,
        seeHistoryBtnBool: false,
        historyAllInfo: [],
      },
      viewer: null,

      // 控制卫星是否显示
      dataSimulationBool: true,

      // 控制参数表单显示
      setParaBool: false,

      // 存储卫星模拟轨道数据
      satelliteDataSource: null,

      // 卫星场景
      satelliteScene: null,

      // 卫星开始加载时间
      simulationStartTime: null,
    }

  },
  mounted() {
    this.initCesium()
    // 卫星加载
    this.getSimulationData()
    // // 自动获取障碍物
    // this.setAutoObstacle()
  },

  activated() {

  },

  methods: {
    // #region 初始化
    initCesium() {
      this.viewer = new Cesium.Viewer('cesiumContainer', {

        baseLayer: new Cesium.ImageryLayer(new Cesium.UrlTemplateImageryProvider({
          //23级瓦片的高精度全球影像
          //url:'http://192.168.8.244:30019/tile-server/v1?Layer=bing_map&TileMatrix={z}&TileCol={x}&TileRow={y}'
          //高德
          //url:'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'
          //谷歌
          url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile'
        })),

        //界面右下角全屏按钮
        fullscreenButton: false,
        //界面左下角控制动画的面板
        animation: false,
        //点击地球后的信息框
        infoBox: false,
        //右上角 Help
        navigationHelpButton: false,
        //是否显示地名查找控件
        geocoder: false,
        //是否显示时间线控件
        timeline: true,
        //是否显示图层选择控件
        baseLayerPicker: true,
        //右上角初始化地球位置按钮
        homeButton: false,
        //右上角 2D/3D切换
        sceneModePicker: true,
        shouldAnimate: true,
        //隐藏双击entity时候的聚焦框
        selectionIndicator: false,
        //去除地球外侧光圈
        skyAtmosphere: false
      })

      /**
       * 设置默认图层数据
       * 0:Bing Maps Aerial
       * 1:Bing Maps Aerial with Labels
       * 2:Bing Maps Roads
       * 3:ESRI World Imagery
       * 4:ESRI World Street Map
       * 5:ESRI National Geographic
       * 6:Open­Street­Map
       * 7:Stamen Watercolor
       * 8:Stamen Toner
       * 9:Sentinel-2
       * 10:Blue Marble
       * 11:Earth at night
       * 12:Natural Earth II
       */
      this.viewer.baseLayerPicker.viewModel.selectedImagery = this.viewer.baseLayerPicker.viewModel.imageryProviderViewModels[3] // 3

      //设置初始位置
      // viewer.camera.setView({
      //   destination: Cesium.Cartesian3.fromDegrees(116.75199, 36.55358, 1000000)
      // });

      this.viewer.cesiumWidget.creditContainer.style.display = 'none'

      this.mouseLeftClick()
    },

    // 展开/隐藏参数设置面单
    setParadata() {
      let that = this
      if (!that.setParaBool) {
        that.setParaBool = true;

        if (that.chartData.show) {
          that.showCharts()
        }
        if (that.history.seeHistoryBtnBool) {
          that.history.seeHistoryBtnBool = false;
        }
      }
      else {
        that.setParaBool = false;
      }
    },
    //#endregion

    // #region 卫星模拟
    getSimulationData() {
      let that = this;
      if (that.satelliteDataSource == null) {
        Cesium.CzmlDataSource.load("/czml/satellite.czml").then(function (dataSource) {
          that.satelliteDataSource = dataSource;
          that.viewer.dataSources.add(dataSource).then(function (ds) {
            that.satelliteScene = ds;
            that.viewer.camera.flyHome(0);
          });
        });
        // 记录仿真开始时间
        that.simulationStartTime = Cesium.JulianDate.now();

        that.dataSimulationBool = true;
      } else {
        that.viewer.dataSources.remove(that.satelliteScene, true);
        that.satelliteDataSource = null;
        that.simulationStartTime = null,
          that.dataSimulationBool = false;
      }
    },

    // 获取卫星位置
    getSatellitePositions() {
      let that = this;
      let entities = that.satelliteDataSource.entities.values;

      let result = '';
      entities.forEach(function (entity) {
        let position = entity.position;
        if (position) {
          let availability = entity.availability.get(0);
          let currentTime = Cesium.JulianDate.now();
          let elapsedTime = Cesium.JulianDate.secondsDifference(currentTime, that.simulationStartTime);
          let targetTime = Cesium.JulianDate.addSeconds(availability.start, elapsedTime, new Cesium.JulianDate());

          let cartesianPosition = position.getValue(targetTime);
          if (cartesianPosition) {
            let cartographicPosition = Cesium.Cartographic.fromCartesian(cartesianPosition);
            let latitude = Cesium.Math.toDegrees(cartographicPosition.latitude);
            let longitude = Cesium.Math.toDegrees(cartographicPosition.longitude);
            let height = cartographicPosition.height;
            console.log('卫星: ' + entity.id + ' 经度: ' + longitude.toFixed(6) + ' 纬度: ' + latitude.toFixed(6) + ' 高度: ' + height.toFixed(6));
            result += '卫星:' + entity.id + '\n经度:' + longitude.toFixed(6) + '\n纬度:' + latitude.toFixed(6) + '\n高度:' + height.toFixed(6) + '\n';
          } else {
            that.showNotification('无法获取卫星: ' + entity.id + ' 在指定时间的位置信息。')
          }
        }
      });
      that.showSuccess(result);
    },
    //#endregion

    // #region 监测站

    // 切换分布方式时，初始化数据
    changeReceiveStationType() {
      let that = this
      // 清空之前的加载
      that.setReceiveStation.receiveStationPos = [];
      that.setReceiveStation.clicktextArr = '';

      that.deleteModelsByDescription('监测站');
      that.satellitePosStr = '';
      that.satelliteEntities.forEach(entity => {
        that.viewer.entities.remove(entity);
      });
      that.satelliteEntities = [];
      that.satellitePos.length = 0
      that.simInterferencePosArr = ''
      that.PosErrorArr = ''
      that.detectedInterferencePos = []
      that.deleteModelsByDescription('模拟干扰源')

      // 结果清空
      that.simTime = 0
      that.stationCNRNum = 0
      that.simResultNumList.length = 0
      that.nTimePosAndErr.NTimeInterferencePosDetected = []
      that.nTimePosAndErr.NTimeLocationError = []
      // that.chartData.x = []
      // that.chartData.y = []
      that.chartData.show = false

      // 设置监测站

      // 自动部署时，获取位置
      if (that.setReceiveStation.getType == 2) {
        getReceiveStationInfo().then(response => {
          const rdata = JSON.parse(JSON.stringify(response))
          const code = rdata.code
          const data = rdata.data
          if (code == 200) {
            for (let i = 0; i < data.length; i++) {
              const item = data[i]
              // 填充基站数据parseFloat().toFixed(6)
              that.setReceiveStation.receiveStationPos.push({ name: item.name, latitude: parseFloat(item.lat).toFixed(6), longitude: parseFloat(item.lon).toFixed(6), height: item.height })
              // 界面textarr中展示
              let result = '经度:' + parseFloat(item.lon).toFixed(6) + ';纬度:' + parseFloat(item.lat).toFixed(6) + ';高度:' + item.height
              that.setReceiveStation.clicktextArr += result + '\n'
            }
          }
        }).catch((r) => {
          that.showNotification(r)
        });
      }
    },

    // 开始部署
    async startSetReceiveStation() {
      let that = this


      // 构建五个参数
      let regex = /^\d+,\d+$/; // 匹配数字,数字格式
      if (!regex.test(that.setReceiveStation.leftBottom) || !regex.test(that.setReceiveStation.rightTop)) {
        that.showNotification("监测站范围非法输入！")
        return
      }
      let monitroArea = that.setReceiveStation.leftBottom + ';' + that.setReceiveStation.rightTop;
      let stationDistState = that.setReceiveStation.getType + 1;
      let stationInterStr = that.setReceiveStation.distance;
      let stationNumStr = that.setReceiveStation.number;
      let monitorStationData = ''
      let num = that.setReceiveStation.receiveStationPos.length;
      for (let index = 0; index < num; index++) {
        const element = that.setReceiveStation.receiveStationPos[index];
        monitorStationData += element.longitude + ',' + element.latitude + ';'
      }
      if (monitorStationData.endsWith(';')) {
        monitorStationData = monitorStationData.substring(0, monitorStationData.length - 1);
      }

      // 显示加载动画
      const loading = ElLoading.service({
        lock: true,
        text: '正在部署监测站...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      // 请求后台
      await receiverSim(monitroArea, stationDistState, stationInterStr, stationNumStr, monitorStationData).then(response => {
        const rdata = JSON.parse(JSON.stringify(response))
        const code = rdata.code
        const msg = JSON.parse(rdata.msg)
        loading.close();
        // debugger
        if (code == 200) {
          that.setReceiveStation.clicktextArr = ''
          that.setReceiveStation.receiveStationPos.length = 0
          that.satelliteEntities.forEach(entity => {
            that.viewer.entities.remove(entity);
          });
          that.satelliteEntities = [];
          that.satellitePos.length = 0
          // 部署前先清空
          that.deleteModelsByDescription('监测站');
          // 监测站
          for (let index = 0; index < msg.ReceiverPos.length; index++) {
            const item = msg.ReceiverPos[index];
            // 填充基站数据
            that.setReceiveStation.receiveStationPos.push({ name: '监测站', longitude: parseFloat(item.rpx).toFixed(6), latitude: parseFloat(item.rpy).toFixed(6) })
            // 添加监测站
            that.addSymbols('监测站', item.rpx, item.rpy, '/glb/receiveStation.glb', '监测站')
            // 界面textarr中展示
            let result = '经度:' + parseFloat(item.rpx).toFixed(6) + ';纬度:' + parseFloat(item.rpy).toFixed(6)
            that.setReceiveStation.clicktextArr += result + '\n'
          }

          // 卫星
          for (let index = 0; index < msg.SatellitePos.length; index++) {
            const element = msg.SatellitePos[index];
            const satelliteEntity = that.viewer.entities.add({
              // fromDegrees（经度，纬度，高度，椭球，结果）从以度为单位的经度和纬度值返回Cartesian3位置
              position: Cesium.Cartesian3.fromDegrees(element.spx, element.spy, 1),
              point: {
                // 点的大小（像素）
                pixelSize: 15,
                // 点位颜色，fromCssColorString 可以直接使用CSS颜色
                color: Cesium.Color.fromCssColorString('#0000ff'),
                // 边框颜色
                outlineColor: Cesium.Color.fromCssColorString('#fff'),
                // 边框宽度(像素)
                outlineWidth: 2,
                // 显示在距相机的距离处的属性，多少区间内是可以显示的
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000000),
                // 是否显示
                show: true
              }
            });
            that.satellitePos.push({ name: '卫星', longitude: parseFloat(element.spx).toFixed(6), latitude: parseFloat(element.spy).toFixed(6) })
            that.satelliteEntities.push(satelliteEntity);
            that.satellitePosStr += '经度:' + parseFloat(element.spx).toFixed(6) + ';纬度:' + parseFloat(element.spy).toFixed(6) + '\n'
          }

          // 视野飞到范围中心
          // 将坐标字符串解析为数组
          const leftBottomCoords = that.setReceiveStation.leftBottom.split(',').map(Number);
          const rightTopCoords = that.setReceiveStation.rightTop.split(',').map(Number);
          // 计算中心点坐标
          const centerX = (leftBottomCoords[0] + rightTopCoords[0]) / 2;
          const centerY = (leftBottomCoords[1] + rightTopCoords[1]) / 2;
          that.viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(centerX, centerY, 1000000)
          });
          that.showSuccess("监测站部署成功！")
        }
        else {
          that.showNotification('错误代码：', code)
        }
      }).catch((r) => {
        loading.close();
        that.showNotification(r)
      });
    },
    //#endregion

    // #region 设置干扰源

    // 切换分布方式时，初始化数据
    changeInterferenceSrcType() {
      let that = this
      that.setInterferenceSrc.interferenceSrcInfo = [];
      that.setInterferenceSrc.autotextArr = '';
      that.setInterferenceSrc.clicktextArr = '';

      // 清空
      that.deleteModelsByDescription('干扰源');
      that.simInterferencePosArr = ''
      that.PosErrorArr = ''
      that.detectedInterferencePos = []
      that.deleteModelsByDescription('模拟干扰源')
      // 结果清空
      that.simTime = 0
      that.stationCNRNum = 0
      that.simResultNumList.length = 0
      that.nTimePosAndErr.NTimeInterferencePosDetected = []
      that.nTimePosAndErr.NTimeLocationError = []
      // that.chartData.x = []
      // that.chartData.y = []
      that.chartData.show = false

      // 自动获取处理
      if (that.setInterferenceSrc.getType == 0) {
        getInterferenceDataList().then(response => {
          const rdata = JSON.parse(JSON.stringify(response))
          const code = rdata.code
          const data = rdata.data
          if (code == 200) {
            that.setInterferenceSrc.interferenceSrcInfo = []
            for (let i = 0; i < data.length; i++) {
              const item = data[i]
              that.setInterferenceSrc.interferenceSrcInfo.push({ name: item.name, latitude: item.lat, longitude: item.lon, power: item.power, type: item.type })

              // 界面textarr中展示
              let result = '经度:' + parseFloat(item.lon).toFixed(6) + ';纬度:' + parseFloat(item.lat).toFixed(6) + ';高度:' + item.height + ';功率:' + item.power + 'dBm' + ';类型:' + item.type
              that.setInterferenceSrc.autotextArr += result + '\n'
            }
          }
        }).catch((r) => {
          that.showNotification(r)
        });
      }
    },

    // 开始部署
    async startSetInterferenceSrc() {
      let that = this


      // 构建五个参数
      // * @param monitorArea 监测区域经纬度范围
      // * @param interferenceDistState 干扰源分布方式，0-位置导入，1-随机部署
      // * @param interferencePos 干扰源经纬度坐标(0-位置导入时有效)
      // * @param interferenceNum 干扰源数量(1-随机部署时有效)
      // * @param interferenceSourcePower 各干扰源发射功率
      // * @param interferenceType 各干扰源类型（1-单音，2-多音，3-线性扫频，4-脉冲）
      let regex = /^\d+,\d+$/; // 匹配数字,数字格式
      if (!regex.test(that.setReceiveStation.leftBottom) || !regex.test(that.setReceiveStation.rightTop)) {
        that.showNotification("监测站范围非法输入！")
        return
      }
      let monitorArea = that.setReceiveStation.leftBottom + ';' + that.setReceiveStation.rightTop;
      let interferenceDistState = -1
      let interferencePos = ''
      let interferenceNum = -1
      let interferenceSourcePower = ''
      let interferenceType = ''
      if (that.setInterferenceSrc.getType == 0) {
        interferenceDistState = 0
        interferenceNum = that.setInterferenceSrc.interferenceSrcInfo.length;
        for (let index = 0; index < interferenceNum; index++) {
          const element = that.setInterferenceSrc.interferenceSrcInfo[index];
          interferencePos += element.longitude + ',' + element.latitude + ';'
          interferenceSourcePower += element.power + ','
          interferenceType += element.type + ','
        }
      }
      else if (that.setInterferenceSrc.getType == 1) {
        interferenceDistState = 0
        interferenceNum = that.setInterferenceSrc.interferenceSrcInfo.length;
        for (let index = 0; index < interferenceNum; index++) {
          const element = that.setInterferenceSrc.interferenceSrcInfo[index];
          interferencePos += element.longitude + ',' + element.latitude + ';'
          interferenceSourcePower += element.power + ','
          interferenceType += element.type + ','
        }
      }
      else if (that.setInterferenceSrc.getType == 2) {
        interferenceDistState = 1
        interferenceNum = that.setInterferenceSrc.randomInfo.number;
        let typeParts = that.setInterferenceSrc.randomInfo.type.split(',');
        // 检查干扰源类型是否合法
        let isAllNumber = typeParts.every(part => /^\d+$/.test(part));
        if (!isAllNumber || interferenceNum != typeParts.length) {
          that.showNotification("干扰源类型输入非法，请输入用','隔开的数字，要和干扰源数量一致！")
          return
        }
        let powerParts = that.setInterferenceSrc.randomInfo.power.split(',');
        // 检查干扰源功率是否合法
        isAllNumber = powerParts.every(part => /^\d+$/.test(part));
        if (!isAllNumber || interferenceNum != powerParts.length) {
          that.showNotification("干扰源功率输入非法，请输入用','隔开的数字，要和干扰源数量一致！")
          return
        }
        for (let index = 0; index < interferenceNum; index++) {
          const powerPart = powerParts[index];
          const typePart = typeParts[index];
          interferenceSourcePower += powerPart + ',';
          interferenceType += typePart + ',';
        }
      }

      // 规范字符串，去掉最后结尾的分割字符
      if (interferencePos.endsWith(';')) {
        interferencePos = interferencePos.substring(0, interferencePos.length - 1);
      }
      if (interferenceType.endsWith(',')) {
        interferenceType = interferenceType.substring(0, interferenceType.length - 1);
      }
      if (interferenceSourcePower.endsWith(',')) {
        interferenceSourcePower = interferenceSourcePower.substring(0, interferenceSourcePower.length - 1);
      }

      // 显示加载动画
      const loading = ElLoading.service({
        lock: true,
        text: '正在部署干扰源...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      // 请求后台
      await interferenceSim(monitorArea, interferenceDistState, interferencePos, interferenceNum, interferenceSourcePower, interferenceType).then(response => {
        const rdata = JSON.parse(JSON.stringify(response))
        const code = rdata.code
        const msg = JSON.parse(rdata.msg)
        loading.close();
        if (code == 200) {
          that.setInterferenceSrc.interferenceSrcInfo.length = 0
          // 部署前先清空
          that.deleteModelsByDescription('干扰源');

          for (let index = 0; index < msg.InterferencePos.length; index++) {
            const pos = msg.InterferencePos[index];
            const power = msg.InterferenceSourcePower[index].power;
            const type = msg.InterferenceType[index].type;
            // 填充数据
            that.setInterferenceSrc.interferenceSrcInfo.push({ name: '干扰源', longitude: pos.ipx, latitude: pos.ipy, power: power, type: type, })
            // 添加干扰源
            that.addSymbols('干扰源', pos.ipx, pos.ipy, that.setInterferenceSrc.modelUri, '干扰源')
          }

          // 视野飞到范围中心
          // 将坐标字符串解析为数组
          const leftBottomCoords = that.setReceiveStation.leftBottom.split(',').map(Number);
          const rightTopCoords = that.setReceiveStation.rightTop.split(',').map(Number);
          // 计算中心点坐标
          const centerX = (leftBottomCoords[0] + rightTopCoords[0]) / 2;
          const centerY = (leftBottomCoords[1] + rightTopCoords[1]) / 2;
          that.viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(centerX, centerY, 1000000)
          });
          that.showSuccess("干扰源部署成功！")
        }
      }).catch((r) => {
        loading.close();
        that.showNotification(r)
      });

    },


    // 清空当前
    clearClickForInterferenceSrc() {
      let that = this
      that.setInterferenceSrc.clicktextArr = []
      that.deleteModelsByDescription('干扰源')
    },

    // 点选添加
    clickForInterferenceSrc() {
      let that = this
      // 改变按钮样式
      if (that.setInterferenceSrc.buttonText == '开始点选') {
        that.isSelecting = true
        that.setInterferenceSrc.buttonText = '完成点选'
        that.setInterferenceSrc.handler = new Cesium.ScreenSpaceEventHandler(that.viewer.scene.canvas)
        that.setInterferenceSrc.handler.setInputAction(that.handleInterferenceSrcClick, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      } else {
        that.isSelecting = false
        that.setInterferenceSrc.buttonText = '开始点选'
        if (that.setInterferenceSrc.handler) {
          that.setInterferenceSrc.handler.destroy()
          that.setInterferenceSrc.handler = null
        }
      }
    },

    handleInterferenceSrcClick(event) {
      let that = this
      if (!that.isSelecting) return

      let earthPosition = that.viewer.camera.pickEllipsoid(event.position, that.viewer.scene.globe.ellipsoid)
      let cartographic = Cesium.Cartographic.fromCartesian(earthPosition, that.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
      let lat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(6)); // 转换为数字类型
      let lng = parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(6));
      let height = cartographic.height.toFixed(6)

      // 弹出输入框
      let input = prompt('请输入干扰源功率(单位:dBm)和干扰源类型(1—单音,2—多音,3—线性扫平,4—脉冲),以逗号隔开,例如(15,1):')

      // 使用正则表达式检查输入格式
      let regex = /^\d+,\d+$/; // 匹配数字,数字格式
      let isValidFormat = regex.test(input);

      if (isValidFormat) {
        // 解析输入
        let power = input.split(",")[0]
        let type = input.split(",")[1]

        // 填充数据
        that.setInterferenceSrc.interferenceSrcInfo.push(
          {
            name: '干扰源',
            longitude: lng,
            latitude: lat,
            type: type,
            power: power
          }
        )
        // 场景中加载
        let modelUri = that.setInterferenceSrc.modelUri
        let description = that.setInterferenceSrc.description
        that.addSymbols('干扰源', lng, lat, modelUri, description)
        // 界面textarr中展示
        let result = '经度:' + parseFloat(lng).toFixed(6) + ';纬度:' + parseFloat(lat).toFixed(6) + ';高度:' + height + ';功率:' + power + 'dBm' + ';类型:' + type
        that.setInterferenceSrc.clicktextArr += result + '\n'

        // 使用flyTo方法飞到该位置
        that.viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(lng, lat, 1000000),
          duration: 1.0 // 飞行持续时间，单位为秒
        });
      }

    },
    //#endregion

    // #region 分析计算
    startCounting() {
      let that = this;

      // 计算干扰定位和分析干扰误差
      if (!that.calInterferencePosAndErr()) {
        return
      }
      that.showCharts()
    },

    // 计算干扰定位和分析干扰误差
    calInterferencePosAndErr() {
      let that = this
      /**
       * @param receiverPos 监测站的位置
       * @param satellitePos 卫星的位置
       * @param interferencePos 干扰源的位置
       * @param interferenceNum 干扰源的数量
       * @param interferenceSourcePower 各干扰源的发射功率
       * @param interferenceType 各干扰源的类型
       * @param simTime 仿真次数
       * @return StationPos(监测站位置坐标) 和 StationCNR_t(载噪比数据) 和 InterferencePos(真实干扰源位置坐标)
       */
      // param1 receiverPos
      let receiverPos = ''
      if (that.setReceiveStation.receiveStationPos.length == 0) {
        that.showNotification("请先部署接收站！")
        return false
      }
      for (let index = 0; index < that.setReceiveStation.receiveStationPos.length; index++) {
        const element = that.setReceiveStation.receiveStationPos[index];
        receiverPos += element.longitude + ',' + element.latitude + ',0;'
      }
      if (receiverPos.endsWith(';')) {
        receiverPos = receiverPos.substring(0, receiverPos.length - 1);
      }

      // param2 satellitePos
      let satellitePos = ''
      if (that.satellitePos.length == 0) {
        that.showNotification("请先部署接收站，获取卫星数据！")
        return false
      }
      for (let index = 0; index < that.satellitePos.length; index++) {
        const element = that.satellitePos[index];
        satellitePos += element.longitude + ',' + element.latitude + ',0;'
      }
      if (satellitePos.endsWith(';')) {
        satellitePos = satellitePos.substring(0, satellitePos.length - 1);
      }

      // param3 interferencePos
      // param4 interferenceNum
      // param5 interferenceSourcePower
      // param6 interferenceType
      let interferencePos = ''
      let interferenceNum = that.setInterferenceSrc.interferenceSrcInfo.length
      let interferenceSourcePower = ''
      let interferenceType = ''

      if (that.setInterferenceSrc.interferenceSrcInfo.length == 0) {
        that.showNotification("请先部署干扰源！")
        return false
      }
      for (let index = 0; index < interferenceNum; index++) {
        const element = that.setInterferenceSrc.interferenceSrcInfo[index];
        interferencePos += element.longitude + ',' + element.latitude + ',0;'
        interferenceSourcePower += element.power + ','
        interferenceType += element.type + ','
      }
      if (interferencePos.endsWith(';')) {
        interferencePos = interferencePos.substring(0, interferencePos.length - 1);
      }
      if (interferenceSourcePower.endsWith(',')) {
        interferenceSourcePower = interferenceSourcePower.substring(0, interferenceSourcePower.length - 1);
      }
      if (interferenceType.endsWith(',')) {
        interferenceType = interferenceType.substring(0, interferenceType.length - 1);
      }
      if(that.simTime == 0)
      {
        that.showNotification("请设置仿真次数！")
        return false
      }
      // // param7 simTime
      let simTime = that.simTime
      // 显示加载动画
      const loading = ElLoading.service({
        lock: true,
        text: '正在计算干扰定位和分析干扰误差...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      // 请求后台
      interferenceAnalyzeStatic(receiverPos, satellitePos, interferencePos, interferenceNum, interferenceSourcePower, interferenceType, simTime).then(response => {
        const rdata = JSON.parse(JSON.stringify(response))
        const code = rdata.code
        const msg = JSON.parse(rdata.msg)
        loading.close();
        if (code == 200) {
          that.nTimePosAndErr.NTimeInterferencePosDetected = []
          that.nTimePosAndErr.NTimeLocationError = []
          that.chartData.x = []
          that.chartData.y = []
          for (let index = 0; index < simTime; index++) {
            // 保存定位
            const interferencePosDetecteds = msg.NTimeInterferencePosDetected[index];
            let tempPos = [];
            for (let index1 = 0; index1 < interferencePosDetecteds.length; index1++) {
              const interferencePosDetected = interferencePosDetecteds[index1];
              tempPos.push({ x: interferencePosDetected.ifpdx, y: interferencePosDetected.ifpdy })
            }
            that.nTimePosAndErr.NTimeInterferencePosDetected.push(tempPos)

            // 保存定位误差
            const locationErrors = msg.NTimeLocationError[index];
            let tempErr = [];
            for (let index1 = 0; index1 < locationErrors.length; index1++) {
              const err = locationErrors[index1];
              tempErr.push(err)
            }
            that.nTimePosAndErr.NTimeLocationError.push(tempErr)

          }

          // 统计展示平均误差            
          for (let index1 = 0; index1 < msg.NTimeLocationErrorAvg.length; index1++) {
            that.chartData.x.push(index1 + 1)
            that.chartData.y.push(msg.NTimeLocationErrorAvg[index1])
          }

          that.showSuccess("计算干扰定位和分析干扰误差成功\n")

          // 更新干扰定位中的仿真结果次数
          that.simResultNumList.length = 0
          for (let index = 1; index <= that.simTime; index++) {
            that.simResultNumList.push({ label: index, value: index })
          }
        }
      }).catch((r) => {
        loading.close();
        that.showNotification(r)
      });

    },

    showCharts() {
      let that = this;
      that.chartData.show = true
      that.$nextTick(() => {
        var chartDom = document.getElementById('drawChart');
        var chartInit = echarts.init(chartDom);

        var option = {
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow'
            }
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
          },
          xAxis: [
            {
              type: 'category',
              data: that.chartData.x,
              axisTick: {
                alignWithLabel: true
              }
            }
          ],
          yAxis: [
            {
              type: 'value'
            }
          ],
          series: [
            {
              name: 'Direct',
              type: 'bar',
              barWidth: '60%',
              data: that.chartData.y,
              itemStyle: {
                color: '#409eff' // 设置柱状图颜色为绿色
              }
            }
          ]
        };
        option && chartInit.setOption(option);
      });
    },
    // #endregion

    //#region 结果展示    
    selectstationCNRNum(val) {
      // debugger
      let that = this
      that.stationCNRNum = val
      that.simInterferencePosArr = ''
      that.PosErrorArr = ''
      that.detectedInterferencePos = []
      that.deleteModelsByDescription('模拟干扰源')

      // 展示选中的模拟干扰源
      let currentPos = that.nTimePosAndErr.NTimeInterferencePosDetected[val - 1]
      for (let index = 0; index < currentPos.length; index++) {
        const element = currentPos[index];
        that.simInterferencePosArr += "经度：" + parseFloat(element.x).toFixed(6) + ",纬度：" + parseFloat(element.y).toFixed(6) + ";\n"
        that.addSymbols("模拟干扰源", element.x, element.y, that.setInterferenceSrc.fakerModelUri, "模拟干扰源")
      }
      // 视野飞到范围中心
      // 将坐标字符串解析为数组
      const leftBottomCoords = that.setReceiveStation.leftBottom.split(',').map(Number);
      const rightTopCoords = that.setReceiveStation.rightTop.split(',').map(Number);
      // 计算中心点坐标
      const centerX = (leftBottomCoords[0] + rightTopCoords[0]) / 2;
      const centerY = (leftBottomCoords[1] + rightTopCoords[1]) / 2;
      that.viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(centerX, centerY, 1000000)
      });

      // 误差展示
      let currentErr = that.nTimePosAndErr.NTimeLocationError[val - 1]
      that.PosErrorArr = "每个干扰源的定位误差:\n"
      for (let index = 0; index < currentErr.length; index++) {
        const element = currentErr[index];
        that.PosErrorArr += parseFloat(element).toFixed(6) + '\n'
      }

      that.showSuccess("第" + val + "组干扰源定位和定位误差展示成功\n")
    },


    //#endregion

    // #region 结果入库
    pushParamAndResultToSql() {
      let that = this
      if (that.currentInfo.simTime == 0) {
        that.showNotification("请先进行分析计算！")
        return
      }


      that.currentInfo.rangeLB = that.setReceiveStation.leftBottom
      that.currentInfo.rangeRT = that.setReceiveStation.rightTop
      that.currentInfo.stationType = that.setReceiveStation.getType
      that.currentInfo.stationGridDis = that.setReceiveStation.distance
      that.currentInfo.stationNum = that.setReceiveStation.number
      that.currentInfo.stationPos = that.setReceiveStation.receiveStationPos
      that.currentInfo.satellitePos = that.satellitePos

      that.currentInfo.interfType = that.setInterferenceSrc.getType
      that.currentInfo.interfAutoTextArr = that.setInterferenceSrc.autotextArr
      that.currentInfo.interfClickTextArr = that.setInterferenceSrc.clicktextArr
      that.currentInfo.interfRandNum = that.setInterferenceSrc.randomInfo.number
      that.currentInfo.interfRandType = that.setInterferenceSrc.randomInfo.type
      that.currentInfo.interfRandPower = that.setInterferenceSrc.randomInfo.power
      that.currentInfo.interfPos = that.setInterferenceSrc.interferenceSrcInfo

      that.currentInfo.simTime = that.simTime
      that.currentInfo.nTimePosAndErr = that.nTimePosAndErr
      that.currentInfo.chartData = that.chartData
      that.currentInfo.simResultNumList = that.simResultNumList

      // 显示加载动画
      const loading = ElLoading.service({
        lock: true,
        text: '正在将本次参数和结果保存到数据库...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      saveJszAnalyseData(that.currentInfoName, that.currentInfo).then(response => {
        const rdata = JSON.parse(JSON.stringify(response))
        const code = rdata.code
        loading.close();
        if (code == 200) {
          that.showSuccess("接收站模式分析过程数据保存成功");
        }
      }).catch((r) => {
        loading.close();
        that.showNotification(r)
      });
    },
    //#endregion

    // #region 历史任务
    selectlatestDataNum() {
      let that = this

      // 显示加载动画
      const loading = ElLoading.service({
        lock: true,
        text: '正在获取历史数据...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      // 请求后台
      queryJszLastRecord(that.history.latestDataNum).then(response => {
        const rdata = JSON.parse(JSON.stringify(response))
        const code = rdata.code
        const data = rdata.data
        if (code == 200) {
          that.history.historyAllInfo.length = 0
          for (let index = 0; index < data.length; index++) {
            const element = data[index];
            that.history.historyAllInfo.push(
              {
                id: element.id,
                createTime: that.formatDate(element.createTime),
                name: element.name,
                result: JSON.parse(element.result),
              })
          }
          loading.close();
        }
      }).catch((r) => {
        loading.close();
        that.showNotification(r)
      });
    },

    async seeHistory() {
      let that = this
      that.history.latestDataNum = 5
      if (!that.history.seeHistoryBtnBool) {
        // 显示加载动画
        const loading = ElLoading.service({
          lock: true,
          text: '正在获取历史数据...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });
        // 请求后台
        await queryJszLastRecord(that.history.latestDataNum).then(response => {
          const rdata = JSON.parse(JSON.stringify(response))
          const code = rdata.code
          const data = rdata.data
          if (code == 200) {
            that.history.historyAllInfo.length = 0
            for (let index = 0; index < data.length; index++) {
              const element = data[index];
              that.history.historyAllInfo.push(
                {
                  id: element.id,
                  createTime: that.formatDate(element.createTime),
                  name: element.name,
                  result: JSON.parse(element.result),
                })
            }
            loading.close();
          }
        }).catch((r) => {
          loading.close();
          that.showNotification(r)
        });

        that.history.seeHistoryBtnBool = true;
        if (that.setParaBool) {
          that.setParaBool = false;
        }
      }
      else {
        that.history.seeHistoryBtnBool = false;
      }
    },

    // 设置参数
    seeOneHistoryInfo(row){
      let that = this

      that.history.seeHistoryBtnBool = true;
      that.setParaBool = true;

      //////////// 接收站和卫星数据注入看板，上图展示
      that.setReceiveStation.leftBottom = row.result.rangeLB
      that.setReceiveStation.rightTop = row.result.rangeRT
      that.setReceiveStation.getType = row.result.stationType
      that.setReceiveStation.distance = row.result.stationGridDis
      that.setReceiveStation.number = row.result.stationNum
      that.setReceiveStation.receiveStationPos = row.result.stationPos
      that.satellitePos = row.result.satellitePos
      // 视野飞到范围中心
      const leftBottomCoords = that.setReceiveStation.leftBottom.split(',').map(Number);
      const rightTopCoords = that.setReceiveStation.rightTop.split(',').map(Number);
      const centerX = (leftBottomCoords[0] + rightTopCoords[0]) / 2;
      const centerY = (leftBottomCoords[1] + rightTopCoords[1]) / 2;
      that.viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(centerX, centerY, 1000000)
      });
      // 监测站上图
      that.setReceiveStation.clicktextArr = ''
      that.deleteModelsByDescription('监测站');
      for (let index = 0; index < that.setReceiveStation.receiveStationPos.length; index++) {
        const item = that.setReceiveStation.receiveStationPos[index];
        // 添加监测站
        that.addSymbols('监测站', item.longitude, item.latitude, '/glb/receiveStation.glb', '监测站')
        // 界面textarr中展示
        let result = '经度:' + parseFloat(item.longitude).toFixed(6) + ';纬度:' + parseFloat(item.latitude).toFixed(6)
        that.setReceiveStation.clicktextArr += result + '\n'
      }
      // 卫星上图
      that.satellitePosStr = '';
      that.satelliteEntities.forEach(entity => {
        that.viewer.entities.remove(entity);
      });
      that.satelliteEntities = [];
      for (let index = 0; index < that.satellitePos.length; index++) {
        const element = that.satellitePos[index];
        const satelliteEntity = that.viewer.entities.add({
          // fromDegrees（经度，纬度，高度，椭球，结果）从以度为单位的经度和纬度值返回Cartesian3位置
          position: Cesium.Cartesian3.fromDegrees(parseFloat(element.longitude), parseFloat(element.latitude), 1),
          point: {
            // 点的大小（像素）
            pixelSize: 15,
            // 点位颜色，fromCssColorString 可以直接使用CSS颜色
            color: Cesium.Color.fromCssColorString('#0000ff'),
            // 边框颜色
            outlineColor: Cesium.Color.fromCssColorString('#fff'),
            // 边框宽度(像素)
            outlineWidth: 2,
            // 显示在距相机的距离处的属性，多少区间内是可以显示的
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000000),
            // 是否显示
            show: true
          }
        });
        that.satelliteEntities.push(satelliteEntity);
        that.satellitePosStr += '经度:' + parseFloat(element.longitude).toFixed(6) + ';纬度:' + parseFloat(element.latitude).toFixed(6) + '\n'
      }

      // 干扰源数据注入看板，上图展示
      that.setInterferenceSrc.getType = row.result.interfType
      that.setInterferenceSrc.autotextArr = row.result.interfAutoTextArr
      that.setInterferenceSrc.clicktextArr = row.result.interfClickTextArr
      that.setInterferenceSrc.randomInfo.number = row.result.interfRandNum
      that.setInterferenceSrc.randomInfo.type = row.result.interfRandType
      that.setInterferenceSrc.randomInfo.power = row.result.interfRandPower
      that.setInterferenceSrc.interferenceSrcInfo = row.result.interfPos
      // 部署前先清空
      that.deleteModelsByDescription('干扰源');
      for (let index = 0; index <that.setInterferenceSrc.interferenceSrcInfo.length; index++) {
        const pos = that.setInterferenceSrc.interferenceSrcInfo[index];
         // 添加干扰源
        that.addSymbols('干扰源', pos.longitude, pos.latitude, that.setInterferenceSrc.modelUri, '干扰源')
      }
      
      // 结果数据注入看板，上图展示
      // 清空之前
      that.stationCNRNum = 0
      that.simInterferencePosArr = ''
      that.PosErrorArr = ''
      that.deleteModelsByDescription('模拟干扰源')

      that.simTime = row.result.simTime
      that.nTimePosAndErr = row.result.nTimePosAndErr
      that.chartData = row.result.chartData
      that.simResultNumList = row.result.simResultNumList
      that.showCharts()
      that.currentInfoName = row.name
    },
    //#endregion

    // #region 公共方法

    // 格式化时间
    formatDate(createTime) {
      const date = new Date(createTime);
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      const hours = String(date.getHours()).padStart(2, '0');
      const minutes = String(date.getMinutes()).padStart(2, '0');
      const seconds = String(date.getSeconds()).padStart(2, '0');
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    },
    // 在场景中添加模型
    addSymbols(itemName, lon, lat, modelUri, description) {
      let that = this
      //位置（弧度单位）
      let position = Cesium.Cartesian3.fromDegrees(parseFloat(lon), parseFloat(lat), 500)

      let entity = that.viewer.entities.add({
        name: itemName,
        description: description, // 这是模型的描述属性，可以是html标签
        position: position,
        model: {
          // uri : "https://data.mars3d.cn/gltf/mars/feiji.glb",
          uri: modelUri,
          minimumPixelSize: 128,
          maximumScale: 20000
        }
      })
    },

    // 检查是否已经存在具有相同名称的模型
    isModelNameExists(name) {
      let that = this;
      let entities = that.viewer.entities.values;

      for (let i = 0; i < entities.length; i++) {
        let entity = entities[i];
        if (entity.model && entity.name == name) {
          return "在场景中已存在描述为“" + entity.description + "”，名称为“" + entity.name + "”的模型";
        }
      }

      return null;
    },

    // 在场景中删除名称为“name”的模型
    deleteModelsByName(name) {
      let that = this
      let entities = that.viewer.entities.values;

      // 从后往前遍历，以避免删除时索引出错
      for (let i = entities.length - 1; i >= 0; i--) {
        let entity = entities[i];
        if (entity.name == name) {
          that.viewer.entities.remove(entity);
          that.showSuccess(`名称为“${name}”的模型已被删除`);
        }
      }
    },

    // 场景中删除描述为“description”的模型
    deleteModelsByDescription(description) {
      let that = this
      let entities = that.viewer.entities.values;

      // 从后往前遍历，以避免删除时索引出错
      for (let i = entities.length - 1; i >= 0; i--) {
        let entity = entities[i];
        if (entity.description == description) {
          that.viewer.entities.remove(entity);
        }
      }
    },
    // 警告信息
    showNotification(message) {
      this.$notify({
        title: '警告',
        message: message,
        type: 'warning',
        duration: 0  // duration 为 0 表示不会自动关闭
      });
    },
    // 成功信息
    showSuccess(message) {
      // 替换 message 中的 \n 为 <br> 元素
      message = message.replace(/\n/g, '<br />');

      this.$notify({
        title: '成功',
        message: `<div style="white-space: pre-line;">${message}</div>`,
        type: 'success',
        dangerouslyUseHTMLString: true,
        duration: 2000  // duration 为 0 表示不会自动关闭
      });
    },

    //左击事件
    mouseLeftClick() {
      let _this = this
      let handler = new Cesium.ScreenSpaceEventHandler(_this.viewer.scene.canvas)
      let result = ''
      handler.setInputAction(function (event) {
        let earthPosition = _this.viewer.camera.pickEllipsoid(event.position, _this.viewer.scene.globe.ellipsoid)
        let cartographic = Cesium.Cartographic.fromCartesian(earthPosition, _this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
        let lat = Cesium.Math.toDegrees(cartographic.latitude)
        let lng = Cesium.Math.toDegrees(cartographic.longitude)
        let height = cartographic.height
        console.log('mouseLeftClick' + '当前经纬度====' + lng + '维度 =====' + lat + '高度 =====' + height)
        result = '经度:' + lng + ';维度:' + lat + ';高度:' + height + '\n'
        if (_this.region_switch) {
          if (_this.clickCount == 0) {
            _this.region_x1 = lng
            _this.region_y1 = lat
          }

          if (_this.clickCount == 1) {
            _this.region_x2 = lng
            _this.region_y2 = lat
          }
          _this.clickCount++
        }

      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

      return result
    },

    //#endregion
  }

}

</script>

<style >
#cesiumContainer {
  width: 100%;
  height: 92vh;
}

.setParadata {
  border-radius: 5px;
  height: 32px;
  width: auto;
  position: absolute;
  right: 285px;
  top: 8px;
  color: #ffffff;
  background: rgb(0, 145, 255);
  border: 1px solid #303336;
  background-size: cover;
  z-index: 6;
}

.setParadata:hover {
    color: #fff;
    fill: #fff;
    background: rgba(0, 145, 255, 0.619);
    background-size: cover;
    border-color: rgb(170, 242, 255);
    box-shadow: 0 0 8px #fff;
}

.data-simulation {
  border-radius: 5px;
  height: 32px;
  width: auto;
  position: absolute;
  right: 185px;
  top: 8px;
  color: #ffffff;
  background: rgb(0, 145, 255);
  border: 1px solid #303336;
  background-size: cover;
  z-index: 6;
  cursor: pointer;
}

.data-simulation:hover {
    color: #fff;
    fill: #fff;
    background: rgba(0, 145, 255, 0.619);
    background-size: cover;
    border-color: rgb(170, 242, 255);
    box-shadow: 0 0 8px #fff;
}

.seeHistoryBtn {
  border-radius: 5px;
  height: 32px;
  width: auto;
  position: absolute;
  right: 85px;
  top: 8px;
  color: #ffffff;
  background: rgb(0, 145, 255);
  border: 1px solid #303336;
  background-size: cover;
  z-index: 6;
  cursor: pointer;
}

.seeHistoryBtn:hover {
    color: #fff;
    fill: #fff;
    background: rgba(0, 145, 255, 0.619);
    background-size: cover;
    border-color: rgb(170, 242, 255);
    box-shadow: 0 0 8px #fff;
}

.pos-simulation {
  border-radius: 5px;
  height: 32px;
  width: auto;
  position: absolute;
  right: 100px;
  top: 8px;
  color: #2b0700;
  background: #48b;
  border: 1px solid #303336;
  background-size: cover;
  z-index: 6;
  cursor: pointer;
}

.right-menu {
  border-radius: 5px;
  height: 86%;
  width: 420px;
  position: absolute;
  right: 20px;
  top: 50px;
  color: #2b0700;
  background: #ffffff;
  border: 1px solid #303336;
  background-size: cover;
  z-index: 6;
  overflow-y: auto;
  padding: 5px;
}


.history-menu {
  border-radius: 5px;
  width: 46%;
  height: 30%;
  /* 将高度设置为400px */
  position: fixed;
  top: 80%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #2b0700;
  background: #ffffff;
  border: 1px solid #303336;
  background-size: cover;
  z-index: 6;
}

.history-table {
  height: 80%;
  width: 100%;
  overflow-y: auto;
}

.history-table .el-table__header th {
    font-size: 18px; /* Adjust the size as needed */
    font-weight: bold; /* Optional: Make the text bold */
  }


.cesium-widget-credits {
  /* 去除logo */
  display: none !important;
}

.form-item-full-width {
  height: 10px;
  width: 100%;
}

.coordinates-row {
  display: flex;
  align-items: center;
}

.form-item-inline {
  height: 5px;
  margin-right: 5px;
}

.el-notification {
  white-space: pre !important;
}

</style>
